﻿using System;
using System.Collections.Generic;
using Microsoft.ML;
using Microsoft.ML.Data;

namespace CSharpTest
{
    class Program
    {
        public class HouseData
        {
            public float Size { set; get; }

            public float Price { set; get; }

        }

        public class Prediction
        {
            [ColumnName("Score")]
            public float Price { set; get; }

        }

        static void Main(string[] args)
        {
            #region 训练模型，保存模型
            //MLContext mLContext = new();

            ////1.Import or create training data
            //List<HouseData> houseDatas = new();
            //for (int i = 0; i < 10000; i++)
            //{
            //    houseDatas.Add(new() { Size = i, Price = i + 1 });
            //}
            //IDataView trainingData = mLContext.Data.LoadFromEnumerable(houseDatas);

            ////2.Specify data preparation and model training pipeline
            //var pipeline = mLContext.Transforms.Concatenate("Features", new[] { "Size" }).Append(mLContext.Regression.Trainers.Sdca(labelColumnName: "Price", maximumNumberOfIterations: 10000));

            ////3.Train model
            //var model = pipeline.Fit(trainingData);

            ////4.Make a prediction
            //var size = new HouseData() { Size = 10 };
            //var price = mLContext.Model.CreatePredictionEngine<HouseData, Prediction>(model).Predict(size);

            ////5.Save model
            //mLContext.Model.Save(model, trainingData.Schema, @"model.zip");

            //Console.WriteLine($"Predicted price for size:{size.Size} sq ft={price.Price:C}k");

            #endregion

            #region 模型评估
            //var testHouseDataView = mLContext.Data.LoadFromEnumerable(houseDatas);
            //var testPriceDataView = model.Transform(testHouseDataView);

            //var metrics = mLContext.Regression.Evaluate(testPriceDataView, labelColumnName: "Price");

            //Console.WriteLine($"R^2: {metrics.RSquared:0.##}");
            //Console.WriteLine($"RMS error: {metrics.RootMeanSquaredError:0.##}");
            #endregion


            #region 引入模型，使用模型
            MLContext mLContext = new();
            var model = mLContext.Model.Load(@"model.zip", out DataViewSchema schema);

            for(int i = 10001; i <= 10010; i++)
            {
                var size = new HouseData() { Size = i };
                var price = mLContext.Model.CreatePredictionEngine<HouseData, Prediction>(model).Predict(size);
                Console.WriteLine($"Predicted price for size:{size.Size} sq ft={price.Price:f0}");
            }
            for (int i = -10010; i <= -10001; i++)
            {
                var size = new HouseData() { Size = i };
                var price = mLContext.Model.CreatePredictionEngine<HouseData, Prediction>(model).Predict(size);
                Console.WriteLine($"Predicted price for size:{size.Size} sq ft={price.Price:f0}");
            }

            #endregion
        }
    }
}
